package com.msun.auth.utils;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public final class ReflectUtils {
    /**
     * 用map给target对象赋值
     **/
    public static <T> void mapAssignmentObject(Map<String, Object> map, T t) throws IllegalAccessException {
        Class<?> aClass = t.getClass();
        map.forEach((key, val) -> {
            try {
                Method method = aClass.getMethod("set" + StrUtils.toUpperCaseFirstOne(key), val.getClass());
                method.invoke(t, val);
            } catch (Exception e) {

            }
        });
    }

    /**
     * 用Target对象给map赋值
     **/
    public static <T> void objectAssignmentMap(T t, Map<String, Object> map) throws IllegalAccessException {
        Class<?> aClass = t.getClass();
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if (methodName.startsWith("get") && !methodName.endsWith("Class")) {
                try {
                    Object val = method.invoke(t);
                    map.put(StrUtils.toLowerCaseFirstOne(methodName.replaceFirst("get", "")), val);
                } catch (InvocationTargetException ignored) {
                }
            }
        }
    }

    public static <T> void objectAssignmentStringMap(T t, Map<String, Object> map) {
        try {
            Class<?> aClass = t.getClass();
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                if (methodName.startsWith("get") && !methodName.endsWith("Class")) {
                    try {
                        Object val = method.invoke(t);
                        map.put(StrUtils.toLowerCaseFirstOne(methodName.replaceFirst("get", "")), String.valueOf(val));
                    } catch (InvocationTargetException ignored) {
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 用Source给Target赋值
     **/
    public static <S, T> void objectAssignmentObject(S s, T t) {
        try {
            Class<?> sClass = s.getClass();
            Class<?> tClass = t.getClass();
            Method[] methods = sClass.getMethods();
            for (Method method : methods) {
                String methodName = method.getName();
                if (methodName.startsWith("get") && !methodName.endsWith("Class")) {
                    try {
                        Object val = method.invoke(s);
                        Method tMethod = tClass.getMethod(methodName.replaceFirst("get", "set"), method.getReturnType());
                        tMethod.invoke(t, val);
                    } catch (NoSuchMethodException | InvocationTargetException e) {
                        continue;
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 用Source给Target赋值
     **/
    public static <S, T> void objectAssignmentObjectIgnoreNullAndDefaultValue(S s, T t) throws IllegalAccessException {
        Class<?> sClass = s.getClass();
        Class<?> tClass = t.getClass();
        Method[] methods = sClass.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if (methodName.startsWith("get") && !methodName.endsWith("Class")) {
                try {
                    Object val = method.invoke(s);
                    if (val == null) {
                        continue;
                    }
                    if (val.getClass() == String.class && StringUtils.isNotBlank(String.valueOf(val))) {
                        continue;
                    } else if (val.getClass() == Integer.class && ((Integer) val) == 0) {
                        continue;
                    } else if (val.getClass() == Double.class && ((Double) val) == 0.0) {
                        continue;
                    } else if (val.getClass() == Long.class && ((Long) val) == 0L) {
                        continue;
                    } else if (val.getClass() == Float.class && ((Float) val) == 0L) {
                        continue;
                    }
                    Method tMethod = tClass.getMethod(methodName.replaceFirst("get", "set"), method.getReturnType());
                    tMethod.invoke(t, val);
                } catch (NoSuchMethodException | InvocationTargetException e) {
                    continue;
                }
            }
        }
    }

    /**
     * 用Source给Target赋值
     **/
    public static <S, T> void objectAssignmentObjectIgnoreNull(S s, T t) throws IllegalAccessException {
        Class<?> sClass = s.getClass();
        Class<?> tClass = t.getClass();
        Method[] methods = sClass.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            if (methodName.startsWith("get") && !methodName.endsWith("Class")) {
                try {
                    Object val = method.invoke(s);
                    if (val == null) {
                        continue;
                    }
                    Method tMethod = tClass.getMethod(methodName.replaceFirst("get", "set"), method.getReturnType());
                    tMethod.invoke(t, val);
                } catch (NoSuchMethodException | InvocationTargetException e) {
                    continue;
                }
            }
        }
    }
}
